// 简单模拟实现命令行解释器
#include <iostream>
#include <stdio.h>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

#define SIZE 33
#define MAX_SIZE 1024

string buffer;  // 用户缓冲区
char* com_line[SIZE];  // 分隔之后的命令行
string com_str[SIZE];
char path[MAX_SIZE] = {0};  // 存储当前路径

int main()
{
    while (true)
    {
        if (NULL == getcwd(path, MAX_SIZE)) perror("getcwd:");  // getcwd获取当前进程所在的绝对路径 返回NULL表示出错
        int begin = 0;
        for (int i = 0; i < MAX_SIZE; ++i)
        {
            if (path[i] == '/') begin = i + 1;
            if (path[i] == '\0') break;
        }
        cout << "[MyShell@centos " << path + begin <<  "]$ ";
        
        getline(cin, buffer);  // ls -l -a
        // 分割字符串
        int index = 0, num = 0;
        while (!buffer.empty())
        {
            if (index == SIZE)
            {
                cout << "命令行输入失败,最多支持32个选项输入" << endl;
                break;
            }
            if (buffer[num] == ' ' || num == buffer.size()) 
            {
                com_str[index++] = buffer.substr(0, num);
                if (num != buffer.size()) buffer = buffer.substr(num + 1);
                else break;
                num = 0;
            }
            else num++;
        }
        for (int i = 0; i < index; ++i) com_line[i] = (char*)com_str[i].c_str();

        if (com_str[0] == "ls") com_line[index++] = (char*)"--color=auto";
        com_line[index] = NULL;

        // 进程替换，创建子进程进行完成：
        if (com_str[0] == "cd")  // "cd"操作需要父进程自己进行操作转换哦
        {
            if (com_line[1] != NULL) chdir(com_line[1]);
        }
        else
        {
            pid_t id = fork();
            if (id == 0)
            {
                // 子进程
                execvp(com_line[0], com_line);
                exit(1);
            }
            // 父进程
            int status = 0;
            if (waitpid(id, &status, 0) > 0) cout << "exit code:" << WEXITSTATUS(status) << endl;
        }
    }

    return 0;
}